#include <SDL.h>
#include <SDL_opengl.h>

#include <iostream>
#include <boost/lexical_cast.hpp>

#include "Application.h"
#include <IL/ilut.h>

using namespace std;
using namespace boost;

int main(int argc, char **argv)
{
  if(argc!=6) {
    cout<<"./Useage: binary -w width -h height namename.map"<<endl;
    return 1;
  }

  ilutInit();
  unsigned int width, height;
  try {
    width = lexical_cast<unsigned int>(argv[2]);
    height = lexical_cast<unsigned int>(argv[4]);
    cout<<"Window dimensions: ("<<width<<","<<height<<")"<<endl;
  } catch (bad_lexical_cast &e) {
    cout<<"Could not parse window width and height."<<endl;
    cout<<e.what()<<endl;
    return 1;
  }

  string filename = argv[5];

  if (SDL_Init(SDL_INIT_VIDEO) != 0) {
    cout<<"Unable to initialize SDL: "<<SDL_GetError()<<endl;
    return 1;
  }
  SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
  SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
  SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
  SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 24 );
  SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

  SDL_Surface *screen = NULL;
  screen = SDL_SetVideoMode(width,height,16,SDL_OPENGL);
  if(screen==NULL) {
    cout<<"Could not set requested video mode."<<endl;
    SDL_Quit();
    return 1;
  }
  SDL_FillRect(screen, NULL, SDL_MapRGBA(screen->format,0,0,0,0));

  Graphics::Application app(filename);
  app.InitGL();
  app.Resize(width, height);

  SDL_WM_GrabInput(SDL_GRAB_ON);
  SDL_ShowCursor(SDL_FALSE);
  bool done = false;
  Uint32 lastTick, thisTick, dt;
  lastTick = 0;
  thisTick = SDL_GetTicks();
  SDL_Event E;
  Uint8 *keys = SDL_GetKeyState(NULL);
  int dx, dy;
  bool takeScreenshot = false;
  while(!done)
    {
      dx = 0;
      dy = 0;
      while(SDL_PollEvent(&E))
	{
	  switch(E.type)
	    {
	    case SDL_QUIT:
	      {
		done = true;
	      } break;
	    case SDL_KEYDOWN:
	      {
		keys = SDL_GetKeyState(NULL);
		if(keys[SDLK_ESCAPE])
		  done = true;
		if(keys[SDLK_p])
		  takeScreenshot = true;
	      } break;
	    case SDL_KEYUP:
	      {
		keys = SDL_GetKeyState(NULL);
	      } break;
	    case SDL_VIDEORESIZE:
	      {
		width = E.resize.w;
		height = E.resize.h;
		app.Resize(width, height);
	      } break;
	    case SDL_MOUSEMOTION:
	      {
	        dx += E.motion.xrel;
	        dy += E.motion.yrel;
	      } break;
	    }
	}
      lastTick = thisTick;
      thisTick = SDL_GetTicks();
      dt = thisTick - lastTick;
      app.Update(dt, keys, dx, dy);
      app.Render();

      if(takeScreenshot) {
	cout<<"Took screen."<<endl;
	takeScreenshot = false;

	ILuint ImageName;
	ilGenImages(1, &ImageName);
	ilBindImage(ImageName);
	ilEnable(IL_FILE_OVERWRITE);

	ilutGLScreenie();

	ilDeleteImages(1, &ImageName);
      }

      SDL_GL_SwapBuffers();
    }
  SDL_Quit();

  return 0;
}
